﻿#pragma once

#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QMouseEvent>
#include <QImage>
#include <QWheelEvent>
#include <QGraphicsScene>
#include <QGraphicsSceneWheelEvent>
#include <QScrollBar>
#include <QLabel>
#include <QOpenGLWidget>
#include "qt_graphics_shape_rectangle.h"


class MyQGraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT;
signals:
    void sendMessage(QPointF pos,QString message);
public:
    
    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event)override
    {
        
        QPointF pos = event->pos();
        QColor color = this->pixmap().toImage().pixelColor((int)pos.x(), (int)pos.y());
        QString rgb_string = " b:" + QString::number(color.blue()) + "g:" + QString::number(color.green()) + "r:" + QString::number(color.red());

        QString message = "x:" + QString::number((int)pos.x()) + " y:" + QString::number((int)pos.y()) + rgb_string;
        sendMessage(pos,message);
    }
    void receiveMessage(QPointF pos)
    {
        QColor color = this->pixmap().toImage().pixelColor((int)pos.x(), (int)pos.y());
        QString rgb_string = " b:" + QString::number(color.blue()) + "g:" + QString::number(color.green()) + "r:" + QString::number(color.red());

        QString message = "x:" + QString::number((int)pos.x()) + " y:" + QString::number((int)pos.y()) + rgb_string;
        sendMessage(pos,message);
    }
};


class MyQGraphicsView :  public QGraphicsView
{
public:
    //QGraphicsTextItem   m_text_message;
    //QGraphicsTextItem* m_text_pixel;
    QLabel* m_qlabel_message;
    QLabel* m_qlabel_pixel;
    QGraphicsScene* m_scene;
    QMatrix m_qmatrix;
    double m_scale = 1;
    double m_ratio = 1.1;
    double m_scale_min = 1;
    double m_scale_max = 1;

    MyQGraphicsPixmapItem* m_pixmapItem=nullptr;
    GraphicsShapeRect* m_graphics_shape_rect=nullptr;


    explicit MyQGraphicsView(QWidget* parent)
    :QGraphicsView(parent)
    {
        setViewport(new QOpenGLWidget());
        setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
        m_scene = new QGraphicsScene();
        this->setScene(m_scene);

        m_qlabel_pixel = new QLabel(this);
        m_qlabel_pixel->raise();
        m_qlabel_pixel->resize(300, 20);
        
        m_qlabel_pixel->setStyleSheet("color:green;");
     
        m_qlabel_message = new QLabel(this);
        m_qlabel_message->setAlignment(Qt::AlignTop );
        m_qlabel_message->raise();
        m_qlabel_message->resize(600, 20);
		m_qlabel_message->setStyleSheet("color:green;");

        m_qlabel_message->move(0, 0);
        m_pixmapItem = new MyQGraphicsPixmapItem();
        m_pixmapItem->setAcceptHoverEvents(true);
        m_scene->addItem(m_pixmapItem);
        connect(m_pixmapItem, &MyQGraphicsPixmapItem::sendMessage, this, &MyQGraphicsView::receiveMessage);
    }
    virtual void wheelEvent(QWheelEvent* event)
    {
        QPointF cursorPoint = event->pos();
        QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y()));
        qreal viewWidth = this->viewport()->width();
        qreal viewHeight = this->viewport()->height();

        qreal hScale = cursorPoint.x() / viewWidth;
        qreal vScale = cursorPoint.y() / viewHeight;

        {
            int wheelDeltaValue = event->delta();
            if (wheelDeltaValue > 0)
            {//    Ϲ      Ŵ ;
                double value = m_scale * m_ratio;
                m_scale = value;
                m_qmatrix.setMatrix(m_scale, this->matrix().m12(), this->matrix().m21(), m_scale, this->matrix().dx(), this->matrix().dy());
                this->setMatrix(m_qmatrix, false);
            }
            else
            {
                double value = m_scale / m_ratio;
                if (value >= m_scale_min)
                {
                    m_scale = value;
                    m_qmatrix.setMatrix(m_scale, this->matrix().m12(), this->matrix().m21(), m_scale, this->matrix().dx(), this->matrix().dy());
                    this->setMatrix(m_qmatrix, false);
                }

            }
            QPointF viewPoint = this->matrix().map(scenePos);
            horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
            verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));

        }
    }

    void receiveMessage(QPointF pos,QString message)
    {
        m_qlabel_pixel->setText(message);
//        emit sendPosition(pos);
    }

    void setViewScale(int width, int height)
    {
        double ratiox = double(this->width()) / double(width);
        double ratioy = double(this->height()) / double(height);
        double ratio_image = ratiox < ratioy ? ratiox : ratioy;

        this->m_scale_min = ratio_image;
        this->m_scale = ratio_image;
        QMatrix q;
        q.setMatrix(m_scale, matrix().m12(), matrix().m21(), m_scale, matrix().dx(), matrix().dy());
        setMatrix(q, false);
        m_qlabel_pixel->move(this->width() - 300, 0);  
        return;
    }
    
   
    void setImage(QImage image,QString message)
    {
        if (!image.isNull())
        {
            m_pixmapItem->setPixmap(QPixmap::fromImage(image));
            m_pixmapItem->setScale(1);
            QRectF qrectf = m_pixmapItem->boundingRect();
            m_scene->setSceneRect(qrectf);
            setViewScale(image.width(), image.height());
            m_qlabel_message->setText(message);
        }
        return;
    }
    
    void setRectPose(qreal row1, qreal column1, qreal row2, qreal column2)
    {
        if(m_graphics_shape_rect==nullptr)
        {
            m_graphics_shape_rect = new GraphicsShapeRect( column1,row1, column2-column1,row2-row1,Qt::blue);
            m_scene->addItem(m_graphics_shape_rect);

        }
        m_graphics_shape_rect->setPos(0, 0);
        m_graphics_shape_rect->m_point1->setPos(column1, row1);
        m_graphics_shape_rect->m_point2->setPos(column2, row2);
        m_graphics_shape_rect->update();
        return;
    }

};


